package ucd.smarthome.datastore;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Properties;

import redis.clients.jedis.*;

import com.google.gson.Gson;

import ucd.smarthome.databaseinterface.Appliance;
import ucd.smarthome.databaseinterface.DatabaseInterface;
import ucd.smarthome.databaseinterface.User;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.search.DateTerm;







public class DatabaseImpl implements DatabaseInterface {
	
	private Jedis jedis;
	private String ipaddress="localhost";
	private HashMap<String,String> ActiveMap=new HashMap<>();
	
	public DatabaseImpl() {
		super();
		jedis=new Jedis(ipaddress);
		String appliancesList="";
		jedis.set("ApplianceList", appliancesList);
	}

	@Override
	public boolean storeAppliance(Appliance singleAppliance) {
		String applianceinfo=new Gson().toJson(singleAppliance);
		jedis.set(singleAppliance.getApplianceId(), applianceinfo);
		String sameTypeList="";
		String totalApplianceList="";
		try{
			sameTypeList=jedis.get(singleAppliance.getApplianceName());
			totalApplianceList=jedis.get("totalApplianceList");
			
		}
		
		catch(Exception e){
			return false;
			
		}
		if(checkApplianceExistsInList(sameTypeList, singleAppliance.getApplianceId())){
			
		}
		else{
			sameTypeList=addApplianceToList(sameTypeList, singleAppliance.getApplianceId());
		}
		
		if(checkApplianceExistsInList(totalApplianceList, singleAppliance.getApplianceId())){
			
		}
		else{
			totalApplianceList=addApplianceToList(totalApplianceList,singleAppliance.getApplianceId());
		}
		jedis.set(singleAppliance.getApplianceName(), sameTypeList);
		jedis.set("totalApplianceList",totalApplianceList);
		
		
		return true;
	}

	@Override
	public Appliance getAppliance(String Id) {
		try{
			String result=jedis.get(Id);
			Gson gson=new Gson();
			Appliance appliance=gson.fromJson(result,Appliance.class);
			return appliance;
		}
		catch(Exception e){
			return new Appliance("error", "error", "error", 0, null);
		}

	}

	@Override
	public Appliance[] getAllAppliance() {
		String applist=jedis.get("totalApplianceList");
		String []list=applist.split(";");
		Appliance[] returnlist=new Appliance[list.length];
		for(int i=0;i<list.length;i++){
			returnlist[i]=new Gson().fromJson(jedis.get(list[i]),Appliance.class);
		}
		return returnlist;
	}

	@Override
	public boolean updateAppliance(Appliance singleAppliance) {
		String applianceinfo=new Gson().toJson(singleAppliance);
		jedis.set(singleAppliance.getApplianceId(), applianceinfo);
		return true;
	}

	@Override
	public boolean removeAppliance(String id) {
		jedis.del(id);
		return true;
	}

	@Override
	public boolean activeAppliance(String id) {
		Appliance app=new Gson().fromJson(jedis.get(id), Appliance.class);
		app.setStatus(1);
		jedis.set(id, new Gson().toJson(app));
		return true;
	}

	@Override
	public boolean deactiveAppliance(String id) {
		Appliance app=new Gson().fromJson(jedis.get(id), Appliance.class);
		app.setStatus(0);
		jedis.set(id, new Gson().toJson(app));
		return true;
	}

	@Override
	public User checkUser(String username, String pwd) throws Exception {
		String userinfo=jedis.get(username);
		Gson gson = new Gson();
		try{
			User user=gson.fromJson(userinfo, User.class);
			if(user.getPassword()==pwd){
				return user;
			}
			else{
				sendWarningMail(username, user.getEmail());
				throw new Exception("Password not meet");
			}
		}
		catch(Exception e) {
			throw new Exception("No User Exists");
		}
		
	}

	@Override
	public boolean updateUser(User user) {
		Gson gson=new Gson();
		String userinfo=gson.toJson(user);
		jedis.set(user.getUsername(),userinfo);
		return true;
	}

	@Override
	public boolean deleteUser(String username) throws Exception {
		try{jedis.del(username);
			return true;
		}
		catch(Exception e){
			throw new Exception("No user exists");
		}
	}
	
	
	
	private String addApplianceToList(String list,String id){
		return list.concat(id+';');
		
	}
	
	
	
	private boolean checkApplianceExistsInList(String list,String id){
		return list.contains(id);
	}
	
	
	
	
	
	private void sendWarningMail(String username,String mail){
        Properties props = new Properties();
        Session session = Session.getDefaultInstance(props, null);
        Message msg = new MimeMessage(session);
        String msgBody="Your account "+username+" has detected a illegal login attempt at "+Calendar.getInstance().getTime();
        try {
			msg.setFrom(new InternetAddress("x1destory@gmail.com", "Program Developers"));
	        msg.addRecipient(Message.RecipientType.TO,
            new InternetAddress(mail, "Mr. User"));
	        msg.setSubject("Possible Illegal Action to your Smart Home");
	        msg.setText(msgBody);
	        Transport.send(msg);
		} catch (UnsupportedEncodingException | MessagingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}
}
